home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
prog
/
asm_0_m.arj
/
DELDUPE.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-03-01
|
25KB
|
933 lines
page 74,132
title DELDUPE - Delete duplicate and/or older files
comment |
Syntax:
DELDUPE directory-to-delete [master-directory]
[/O] [/T] [/S] [/V] [/N]
Command line options:
/O delete older files
/N delete files of same name regardless of date/time/size
/S delete similiar files, same date/time but different sizes
/T test mode, list duplicates but do not delete
/V verify, ask for permission to delete each file
/P pause when screen fills
License:
DELDUPE 2.3, Copyright (c) Vernon D. Buerg 1987-89. ALL RIGHTS RESERVED.
DELDUPE is free, but it is a copyrighted work and may be distributed
only pursuant to this license.
Permission is hereby granted to reproduce and disseminate DELDUPE so
long as:
(1) No remuneration of any kind is received in exchange; and
(2) Distribution is without ANY modification to the contents
of DELDUPE.COM, DELDUPE.ASM and all accompanying
documentation and/or support files, including the
copyright notice and this license.
No copy of DELDUPE may be distributed without including a copy
of this license.
Any other use is prohibited without express, written permission in
advance.
Vernon D. Buerg
139 White Oak Circle
Petaluma, CA 94952
CompuServe: 70007,1212 (Go IBMCOM)
Data/BBS: (707) 778-8944 |
page
;
; data area structures
psp struc ; program segment prefix
psp_int_20 db 0cdh,020h ; int 20 instruction
psp_top dw ? ; top of memory in paragraph form
psp_resvl dw ? ; reserved
psp_bytes dw ?,? ; bytes available in segment
db 118 dup (?) ; unused
psp_parm_len db ? ; characters in parameter list
psp_parms db 127 dup (?) ; command parameters
psp ends
dta struc ; data transfer area
dtarsvd db 21 dup (?) ; reserved for DOS
dtaattr db ? ; attribute found
dtatime dw ? ; file's time
dtadate dw ? ; file's date
dtasize dd ? ; file's size (lo,hi)
dtaname db 13 dup (?) ; file name and ext, asciiz form
dta ends
files struc ; file entry in table
filetime dw ? ; file's time
filedate dw ? ; file's date
filesize dd ? ; file's size (lo,hi)
filename db 13 dup (?) ; file name and ext, asciiz form
files ends
file_len equ size files ; size of each file entry
bios segment at 40h ; dos data area
org 84h ;
ega_rows label byte ; rows on screen
bios ends
page
;
; main program - data areas, equates, and constants
cseg segment public para 'code'
assume cs:cseg, ds:cseg, es:nothing
org 100h
deldupe proc far
jmp start ; skip around data areas
; equates
zero equ 0 ; constant
one equ 1 ; constant
bs equ 8 ; backspace
tab equ 9 ; a tabby
cr equ 13 ; and a carriage return
lf equ 10 ; a line feed
eof equ 26 ; end of file marker
blank equ 32 ; a space
idos equ 21h ; dos interrupt 21h functions
dconio equ 08h ; direct console i/o
pstrng equ 09h ; print string
bufcon equ 0ah ; buffered keyboard input
select equ 0eh ; select disk
setdta equ 1ah ; set data transfer area
curdsk equ 19h ; get current disk
chdir equ 3bh ; change current directory
write equ 40h ; write to a file or handle
delete equ 41h ; delete a file
getdir equ 47h ; get current directory
ffirst equ 4eh ; find first matching file
fnext equ 4fh ; find next matching file
switch_char equ '/' ; delimiter for command line switches
path_char equ '\' ; delimiter for path names
drive_char equ ':' ; delimiter for drive letters
stopper equ 255 ; ends print string text
date record year:7,month:4,day:5 ; dos packed date mask
time record hour:5,minute:6,sec:5 ; dos packed time mask
page
;
; messages
usage db cr,' ' ; overwrite the jmp
db cr,lf,'DELDUPE 2.3, Copyright (c) 1987-89, Vernon D. Buerg. ALL RIGHTS RESERVED.'
db cr,lf
db cr,lf,'Usage:'
db cr,lf,tab, 'd:\deldupe directory-to-delete [master-directory]'
db cr,lf,tab,tab,tab, ' [/O] [/T] [/S] [/V] [/P] [/N]'
db cr,lf
db cr,lf,tab, 'Supply drive and \ for each directory.'
db cr,lf,tab, 'If master-directory is omitted, the current directory is used.'
db cr,lf
db cr,lf,tab, '/O delete Older files of same name'
db cr,lf,tab, '/S delete Similar files (diff size only)'
db cr,lf,tab, '/T display filenames but do not delete (Test)'
db cr,lf,tab, '/V Verify the deletion of each file'
db cr,lf,tab, '/P Pause when screen fills'
db cr,lf,tab, '/N delete files of same Name'
null db cr,lf,'$'
db bs,blank,eof ; end of usage display for TYPE
cooking db cr,lf,'Analyzing master directory ... $'
errmsg1 db cr,lf,'No matching files found!',cr,lf,'$'
errmsg2 db cr, 'No duplicate or older files to delete.',cr,lf,'$'
inform1 db 'Same ' ; identical date/time/size
inform2 db 'Older ' ; earlier date/time
inform3 db 'Similar' ; same date, diff size
donemsg db cr,lf ; final summary message
dcount db ' file(s) '
dsize db ' bytes$'
more db cr,lf,'More>','$' ; full screen prompt
prompt db '- delete? $' ; verification prompt
reply db 2,0 ; buffered console read buffer
answer db 0,0 ; their answer
titles db cr,tab,tab,tab, '- Master directory - -- Old directory ---'
db cr,lf,'Reason Filename Bytes Last change Bytes Last change'
db stopper
prtline db cr,lf ; detail print line
prtwhy db 'Similar ' ; reason for deleting
prtname db 12 dup (' ') ; file name and ext
oldsize db ' ' ; file's size
olddate db ' ' ; file's date
oldtime db ' ' ; file's time
prtstop label byte ; stop line here if same
newsize db ' ' ; file's size
newdate db ' ' ; file's date
newtime db ' ' ; file's time
db stopper
prt_len equ $-prtline ; length of print line
page
;
; constants and work areas
flags db 0 ; processing options
older equ 1 ; O = delete older version of files
test equ 2 ; T = display but don't really delete
similar equ 4 ; S = delete if same date/time but diff size
verify equ 8 ; V = ask to confirm each delete
pause equ 10h ; P = pause when screen fills
newer equ 20h ; N = delete regardless of date/time
first equ 40h ; set when headings printed 1st time
max dw 3000 ; maximum table entries (dynamic)
count dw 0 ; total number of table entries used
mcount dw 0 ; number of entries for master dir
ocount dw 0 ; number of entries for old dir
deleted dw 0 ; number of files deleted
delsize dw 0,0 ; sum of deleted file sizes
old_table dw 0 ; ptr to first table entry for old dir
msg1 db cr,lf,'Old path not found -- '
oldpath db 76 dup (0),'$' ; directory to delete from
msg2 db cr,lf,'New path not found -- '
newpath db 76 dup (0),'$' ; master directory
global db '*.*',0 ; for find first/next
curdrv db 0 ; current drive number
crtrows db 0 ; rows on screen
dtawork db 48 dup (0) ; data transfer area
olddrv db ' :\' ; original path for oldpath drive
olddir db 64 dup (0) ; its current directory
newdrv db ' :\' ; original path for newpath drive
newdir db 64 dup (0) ; its current directory
page
;
; set switches from command line
start:
push es ; set dos data area
mov ax,bios ; segment address
mov es,ax ;
mov al,byte ptr es:ega_rows ; dos rows on screen
mov ah,24 ; default max rows
or al,al ; is row value ok?
jz start1 ; no, use default
mov ah,al ; yes,
start1: sub ah,2 ; compensate for heading
mov byte ptr crtrows,ah ; set max rows on screen
pop es ;
mov dx,offset dtawork ; use local dta
mov ah,setdta ; set disk transfer area
int idos ;
mov ah,curdsk ; get current disk
int idos ;
mov curdrv,al ; and save for exit
lea sp,table ; set local stack
mov ax,word ptr ds:psp_bytes ; size of segment
sub ax,pgmsize ; less program size
sub dx,dx ;
mov cx,file_len ; size of each table entry
div cx ; to get maximum entries
mov max,ax ;
mov si,offset psp_parm_len ; point to command line
sub cx,cx ; to receive command line length
lodsb
or cl,al ; any command line?
jnz switches ; yes, continue
error1:
mov dx,offset usage ; operands are missing
sendmsg:
mov ah,pstrng ; print final message
int idos ;
mov ah,chdir ; restore current directory
mov dx,offset olddrv ; for oldpath drive
int idos ;
mov ah,chdir ; restore current directory
mov dx,offset newdrv ; for newpath drive
int idos ;
mov dl,curdrv ; restore current drive
mov ah,select ; via select disk
int idos ;
int 20h ; exit as is
switches:
mov di,offset psp_parms ; offset to command parameters
switches0:
mov al,switch_char ; see if ANY switches
repne scasb
jne switched ; none, skip next
jcxz switched ; no more data
mov byte ptr -1[di],cr ; terminate command line at first /
cmp byte ptr -2[di],blank ;
jne switchesa ;
mov byte ptr -2[di],cr ;
switchesa:
mov si,di ; point to next char
lodsb ; get char following switch char
cmp al,'a' ; and make it upper case
jb switches1 ;
sub al,blank ;
switches1:
cmp al,'O' ; delete older files?
jne switches2 ;
or flags, older ;
switches2:
cmp al,'T' ; display but don't delete?
jne switches3 ;
or flags, test ;
switches3:
cmp al,'S' ; delete similar files?
jne switches4 ;
or flags,similar ;
switches4:
cmp al,'P' ; want to pause when screen fills?
jne switches5 ;
or flags, pause ;
switches5:
cmp al,'V' ; want to verify each delete?
jne switches6 ;
or flags, verify ;
switches6:
cmp al,'N' ; want to delete matching names?
jne switches7 ;
or flags, newer ;
switches7:
jcxz switched ; any more operands?
jmp switches0 ; yup
page
;
; get path names for old and new directories
switched:
mov si,offset psp_parms ; point to command line again
mov cl,byte ptr ds:[psp_parm_len] ; get length back
parm1:
lodsb ; next char
cmp al,blank ; skip leading blanks
je parm1a ;
cmp al,tab ; skip tabs, too
jne parm2 ;
parm1a: loop parm1 ;
jmp error1 ; operand(s) missing
parm2:
mov di,offset oldpath ; target for old path name
sub cx,1 ; account for last lodsb
jg parm3 ; if more to process
jmp error1 ; operand(s) missing
parm3:
stosb ; previous char
lodsb ; next char
cmp al,blank ; have operand separator?
jbe parm4 ; yes, have first op
loop parm3 ;
stosb ;
jmp short parm2a ; no second operand, use curdir
parm4:
mov di,offset newpath ; target for master path name
jcxz parm2a ; if no second operand
parm5:
lodsb ; skip intervening delimiters
cmp al,blank ;
je parm6 ;
cmp al,cr ; end of parameters?
je parm2a ; yes, just one operand
cmp al,tab ; skip tabs
jne parm7 ;
parm6: loop parm5 ; until no more command parameters
parm2a:
mov di,offset newpath ; target for master path name
mov ah,curdsk ; get current drive
int idos ;
mov dl,al ; drive letter for oldpath
add al,'A' ; make into letter
stosb ; set master path name
mov ax,'\:' ; to current drive
stosw ;
inc dl ; letter to drive number
mov ah,getdir ; get current directory
mov si,di ;
int idos ;
mov cx,64 ; maximum length to find end of name
lodsb ; first char of path name
parm7: ; copy 2nd path name to 'newpath'
stosb ; its first/next char
lodsb ; get next command line char
cmp al,cr ; end of it?
jbe check1 ; yes, have both operands now
loop parm7
page
;
; get and save current directory name for drive
; containing old and new (master) directories
check1: ; check if path names are valid
mov ah,curdsk ; get current drive
int idos ;
add al,'A' ; convert to drive letter
mov byte ptr olddrv,al ; and save it
mov word ptr olddrv+1,'\:' ; in original
mov byte ptr newdrv,al ; directory names
mov word ptr newdrv+1,'\:' ; with delimiters
mov dl,0 ; to use current drive
cmp byte ptr oldpath+1,drive_char ; was it supplied?
jne check1a ; yes
mov dl,byte ptr oldpath ; drive supplied with oldpath
and dl,5fh ; insure upper case
mov byte ptr olddrv,dl ; and save
sub dl,'A'-1 ; make into drive number
check1a:
mov ah,getdir ; get current directory
mov si,offset olddir ; for oldpath drive
int idos ;
mov ah,chdir ; change directory
mov dx,offset oldpath ; to supplied oldpath name
int idos ;
jnc check2 ; found it?
mov dx,offset msg1 ; no, issue error message
jmp sendmsg ; and exit
check2:
mov ah,chdir ; restore oldpath current directory
mov dx,offset olddrv ; to original directory
int idos ;
mov dl,0 ; to use current drive
cmp byte ptr newpath+1,drive_char ; was it supplied?
jne check2a ; yes
mov dl,byte ptr newpath ; drive supplied with oldpath
and dl,5fh ; insure upper case
mov byte ptr newdrv,dl ; and save
sub dl,'A'-1 ; make into drive number
check2a:
mov ah,getdir ; get current directory
mov si,offset newdir ; for newpath drive
int idos ;
mov ah,chdir ; change directory
mov dx,offset newpath ; to new path name
int idos ;
jnc checked ; found it?
mov dx,offset msg2 ; no, issue error message
jmp sendmsg ; and exit
checked: ; current directory is now newpath
page
;
; build list of files in master directory
build1:
mov dl,byte ptr newdrv ; reset current drive
sub dl,'A' ; to newpath drive
mov ah,select ; select disk
int idos ;
mov dx,offset cooking ; show that we're working
mov ah,pstrng
int idos
mov di,offset table ; first table spot
mov dx,offset global ; filespec for master directory
mov cx,07h ; file attributes: R+H+S
mov ah,ffirst ; find first matching file
int idos
or ax,ax
jz build12 ; have first file?
mov dx,offset errmsg1 ; oops, now what
jmp sendmsg
build12: ; add master file to the table
lea si,dtawork.dtatime ; point to good stuff
mov cx,file_len ; just this much and some more
rep movsb
inc count ; and bump entry count
mov ax,max ; maximum table entries
cmp count,ax ; exceeded?
jae build2 ; yup, gotta go now
inc mcount ;
build13:
mov ah,fnext ; find next matching file
int idos
or ax,ax ; any more?
jz build12 ; yes, add it into table
page
;
; build list of files in old directory
build2:
mov old_table,di ; save ptr to first oldpath entry
mov dl,byte ptr olddrv ; get drive letter for oldpath
sub dl,'A' ; and convert to drive number
mov ah,select ; change current drive
int idos ; to oldpath
mov dx,offset oldpath ; change current directory
mov ah,chdir ; to oldpath
int idos ;
mov dx,offset global ; filespec for old directory search
mov cx,07h ; file attributes: R+H+S
mov ah,ffirst ; find first matching file
int idos ;
or ax,ax ; have first file?
jz build22 ; yes, add to table
mov dx,offset errmsg1 ; no, empty directory
jmp sendmsg
build22: ; add master file to the table
lea si,dtawork.dtatime ; point to good stuff
mov cx,file_len ; just this much and some more
rep movsb ;
inc count ; and bump entry count
mov ax,max ; maximum table entries
cmp count,ax ; exceeded?
jae find1 ; yup, gotta go now
inc ocount ;
build23:
mov ah,fnext ; find next matching file
int idos
or ax,ax ; any more?
jz build22 ; yes, add it into table
page
;
; look for old/duplicate files now
find1:
mov bx,offset table ; first master entry
find2:
mov bp,old_table ; first entry in old dir
mov dx,ocount ; these many in old dir
find2a: ; compare new/old asciiz file names
lea di,filename[bp] ; its filename part
lea si,filename[bx] ; point to a master dir entry
mov cx,size filename ; filename length
find2b:
lodsb ; file names match?
cmp al,byte ptr [di] ; match so far?
jne find2d ; no, try next oldpath entry
inc di ; yes, point to next char
cmp al,0 ; end of asciiz name?
je compare ; yes, have match
loop find2b ;
jmp compare ; all matched
find2d:
add bp,file_len ; point to next entry
sub dx,1 ; no,
jnz find2a ; any more to check?
jmp skipit ; not found
page
;
; compare old/new file dates, times and sizes
compare:
mov si,bp ; copy oldpath dta data
lea di,dtawork.dtatime ; to work area
mov cx,file_len ; for comparing
rep movsb ; dta fields
lea si,dtawork.dtatime ; compare file data
lea di,word ptr filetime[bx] ; except for attribute byte
mov cx,filename - filetime
repe cmpsb
je purge1 ; different, older or what?
test flags,newer ; don't care about date/time/size?
jnz purge1 ; right, delete matching file names
test flags,older ; allowed to delete older files?
jnz compare1 ; yes, check further
jmp skipit ; no, skip further checks
compare1:
mov si,offset inform2 ; compare dates
mov ax,word ptr dtawork.dtadate
cmp ax,word ptr filedate.[bx]
jb purge2 ; it's older file
je compare2 ; it's the same
jmp skipit ; or newer
compare2:
mov ax,word ptr dtawork.dtatime ; compare times
cmp ax,word ptr filetime.[bx]
jb purge2 ; it's earlier
je compare3 ; or the same
jmp skipit ; or later flavor
compare3:
mov si,offset inform3 ; it same datestamp,
test flags,similar ; but different size
jnz purge2 ; allowed to delete?
jmp skipit ; if /S not supplied
page
;
; print file information
purge1: mov si,offset inform1 ; exact duplicate file
purge2: mov cx,7 ; copy reason to print line
mov di,offset prtwhy ;
rep movsb ;
mov cx,size filename ; copy file name to print line
lea si,dtawork.dtaname ; point to file name
mov di,offset prtname ; to copy here
print1: lodsb ; next filename char
cmp al,zero ; end of name?
je print2 ; yes, ready
stosb ; no, copy next char
loop print1 ; continue
jcxz print3 ; used entire name
print2:
mov al,blank ; pad with spaces
rep stosb
print3: inc deleted ; increment count of files processed
mov dx,word ptr dtawork.dtasize+2
mov ax,word ptr dtawork.dtasize
add delsize+2,dx ; add up total
add delsize,ax ; deleted file
adc delsize+2,0 ; bytes
mov di,offset oldsize ; format master file size
mov dx,word ptr filesize+2[bx]
mov ax,word ptr filesize[bx]
call getsize
mov di,offset olddate ; format date of master file
mov ax,word ptr filedate[bx]
call getdate
mov di,offset oldtime ; format time of master file
mov ax,word ptr filetime.[bx]
call gettime ;
mov prtstop,stopper ; short print line if same
;; cmp word ptr prtwhy,'aS' ; duplicate files?
;; je print4 ; yes, skip redundant info
mov prtstop,blank ; clear print line
mov di,offset newsize ; format new file size
mov dx,word ptr dtawork.dtasize+2
mov ax,word ptr dtawork.dtasize
call getsize
mov di,offset newdate ; format date of new file
mov ax,word ptr dtawork.dtadate
call getdate
mov di,offset newtime ; format time of new file
mov ax,word ptr dtawork.dtatime
call gettime
print4:
test flags, pause ; pause when screen fills?
jz print5 ; no, just print
mov ax,deleted ; number of lines so far
mov cl,byte ptr crtrows ; max lines on screen
div cl ; get page number
or ah,ah ; at end of screen?
jnz print5 ; no,
mov dx,offset more ; yes, prompt
mov ah,pstrng ; for operator action
int idos ;
mov ah,dconio ; wait for a key
int idos ;
and flags,255-first ; insure new headings
print5:
test flags,first ; first time to print?
jnz print6 ; no, already have titles
mov dx,offset titles ; yes, show headings
call prints ;
or flags,first ; and indicate have titles
print6:
mov dx,offset prtline ; print detail line
call prints ;
test flags, test ; just display possible actions?
jnz skipit ; yes, don't really delete
page
;
; delete the duplicate file
test flags, verify ; want to confirm each delete?
jz purge_now ; no, just do it
and flags,255-pause ; /P is superfluous
askem:
mov dx,offset prompt ; display prompt message
mov ah,pstrng ; use print string function
int idos ;
mov dx,offset reply ; point to reply buffer
mov ah,bufcon ; for buffered console i/o
int idos ;
mov al,byte ptr answer ; get their one char answer
and al,5fh ; make it upper case
cmp al, 'Y' ; want to proceed?
je purge_now ; yes
jmp skipit ; no, let null enter skip it
purge_now:
lea dx,dtawork.dtaname ; point to file name
mov ah,delete ; delete a file
int idos ;
jc skipit ; oops, doesn't count
; bump to next table entry
skipit:
add bx,file_len ; point to next file entry
sub mcount,one ; any more?
jle finished ;
jmp find2 ; yup, work work work
; finished processing all table entries
finished:
sub dx,dx ; get count
mov ax,deleted ; of deleted files
mov di,offset dcount ;
call getsize ;
mov dx,delsize+2 ; get total
mov ax,delsize ; deleted file's
mov di,offset dsize ; bytes
call getsize ;
mov dx,offset donemsg ; all done
cmp deleted,zero ; deleted any files?
ja done ; yes, looks good
mov dx,offset errmsg2 ; no, say so
done:
jmp sendmsg ; emit final blank line
page
;
; Format the date
;
; Input: AX contains file date
; DI points to area to fill in with formatted date
getdate proc near ; format the date
or ax,ax ; is it valid?
jz gotdate ; no, quit
push ax ;Save it
and ax,mask month ;Get month part
mov cl,month ;Bits to shift
call cnvrt
cmp al,'0' ; Suppress leading zero
jne getdat1
mov al,' '
getdat1:stosw
mov al,'/'
stosb
pop ax ;Get the date back
push ax
and ax,mask day ;Get day part
mov cl,day ;Bits to shift
call cnvrt
stosw
mov al,'/'
stosb
pop ax
and ax,mask year ;Get year part
mov cl,year ;Bits to shift
call cnvrt
or al,'8' ;Adjust for base year
stosw
gotdate:
ret
getdate endp
; Format the time
;
; Input: AX contains file time
; DI points to area to fill in with formatted time
gettime proc near ; format the date
or ax,ax ; is it valid?
jz gottime
push ax ; save date
and ax,mask hour ; get hour part
mov cl,hour ; mask bits to shift
shr ax,cl
call cnvrt1
stosw
mov al,':'
stosb
pop ax ; get the time back
and ax,mask minute ; get min part
mov cl,minute ; bits to shift
call cnvrt
stosw
gottime:
ret
gettime endp
cnvrt proc near
shr ax,cl
cnvrt1: aam ; make al into bcd
or ax,'00' ; and to ascii
xchg al,ah
cnvrtd: ret
cnvrt endp
Page
;
; Format double word
;
; Input: DX:AX has binary value to format
; DI points to area to fill with formatted ascii number
ddptr Dw 0
getsize proc near ; formats a 32 bit integer
push bp ; in dx:ax
push bx ; to ds:si
push di
push si
mov ddptr,di ; addr of target field
mov di,dx ; routine uses di:si
mov si,ax
call printdw
pop si
pop di
pop bx
pop bp
ret
printdw:
xor ax,ax ; clear work regs
mov bx,ax ;
mov bp,ax ;
mov cx,32 ; bits of precision
j1: shl si,1
rcl di,1
xchg bp,ax
call j6
xchg bp,ax
xchg bx,ax
call j6
xchg bx,ax
adc al,0
loop j1
mov cx,1710h
mov ax,bx
call j2
mov ax,bp
j2: push ax
mov dl,ah
call j3
pop dx
j3: mov dh,dl
shr dl,1 ; move high
shr dl,1 ; nibble to
shr dl,1 ; the low
shr dl,1 ; position
call j4
mov dl,dh
j4: and dl,0fh ; mask low nibble
jz j5 ; if not zero
sub cl,cl
j5: dec ch
and cl,ch
or dl,'0' ; fold in ascii zero
sub dl,cl
mov bx,ddptr
mov [bx],dl ; ptr to next target field
inc ddptr
ret
j6: adc al,al
daa
xchg al,ah
adc al,al
daa
xchg al,ah
ret
getsize endp
page
;
; Print string like int 21h function 9
prints proc near ; dx has offset to string
push di ; ending in char x'ff'
push bx ;
push cx ;
mov di,dx ; ptr to string text
mov cx,-1 ; overall text length
mov al,stopper ; find ending hex ff
repne scasb ;
not cx ; length is bytes scanned
mov bx,1 ; standard output device
mov ah,write ; write to a file or handle
int idos ;
pop cx ; recover registers
pop bx ;
pop di ;
ret ;
prints endp
page
;
; dynamic work areas
even
lstack label byte ; local stack
table equ byte ptr lstack+256 ; contains master file entries
; as many as free memory will permit
pgmsize equ table-cseg+256 ; program, psp and stack size
deldupe endp
cseg ends
end deldupe